home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
rendchar.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
4KB
|
180 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* rendchar -
* convert polygonal outlines into bitmaps
*
* Exports:
* Bitmap *polychartobm(chardesc *cd, mat2d *mat,double linewidth);
*
* Paul Haeberli - 1991
*/
#include "bitmap.h"
#include "math.h"
#include "objfnt.h"
#include "polyscan.h"
#define FUNC_BEGINFACET 1
#define FUNC_ENDFACET 2
#define FUNC_VERTEX 3
static float xmin, xmax;
static float ymin, ymax;
static Bitmap *thebm;
void transpoint2(mat2d *mat,double ix,double iy,double *ox,double *oy)
{
*ox = mat->a*ix+mat->b*iy+mat->tx;
*oy = mat->c*ix+mat->d*iy+mat->ty;
}
static void fillspan(int y, int xmin, int xmax)
{
int p, pxmin, pxmax;
short *sptr;
short mask;
short *bmbase;
if(xmin == xmax) {
thebm->base[y*thebm->sper + (xmin >> 4)] |= (0x8000>>(xmin&0xf));
return;
}
pxmin = xmin>>4;
pxmax = xmax>>4;
bmbase = thebm->base+(y*thebm->sper);
if(pxmin == pxmax) {
mask = (0xffff<<(15-(xmax&0xf))) & (0xffff>>(xmin&0xf));
sptr = bmbase+pxmin;
*sptr |= mask;
} else {
mask = 0xffff>>(xmin&0xf);
sptr = bmbase+pxmin;
*sptr++ |= mask;
for(p=pxmin+1; p<pxmax; p++)
*sptr++ = 0xffff;
mask = 0xffff<<(15-(xmax&0xf));
*sptr |= mask;
}
}
static void initminmax(void)
{
xmin = ymin = 100000.0;
xmax = ymax = -100000.0;
}
static void minmaxfunc(int func, float x, float y)
{
if(func == FUNC_VERTEX) {
if(x<xmin)
xmin = x;
if(x>xmax)
xmax = x;
if(y<ymin)
ymin = y;
if(y>ymax)
ymax = y;
}
}
static void scanfunc(int func, float x, float y)
{
switch(func) {
case FUNC_BEGINFACET:
scanbeginfacet();
break;
case FUNC_ENDFACET:
scanendfacet();
break;
case FUNC_VERTEX:
scanvertex(x,y);
break;
}
}
static void execcharprog(short *sptr, mat2d *mat, void (*func)(int func, float x, float y))
{
int nverts;
double ix, iy, tx, ty;
while(1) {
switch(*sptr++) {
case PO_BGNLOOP:
func(FUNC_BEGINFACET,0.0,0.0);
break;
case PO_ENDBGNLOOP:
func(FUNC_ENDFACET,0.0,0.0);
func(FUNC_BEGINFACET,0.0,0.0);
break;
case PO_RETENDLOOP:
func(FUNC_ENDFACET,0.0,0.0);
return;
break;
case PO_RET:
return;
break;
}
nverts = *sptr++;
while(nverts--) {
ix = sptr[0];
iy = sptr[1];
transpoint2(mat,ix,iy,&tx,&ty);
func(FUNC_VERTEX,tx,ty);
sptr+=2;
}
}
}
Bitmap *polychartobm(chardesc *cd, mat2d *mat,double linewidth)
{
int xsize, ysize;
mat2d mymat;
float hwidth;
if(cd->data) {
scanoutspan(fillspan);
scanoutlinewidth(linewidth);
hwidth = linewidth/2.0;
initminmax();
execcharprog(cd->data,mat,minmaxfunc);
if(xmin<xmax) {
xmin = floor(xmin-hwidth); /* add a bit for the 1/2 pixel bloat */
ymin = floor(ymin-hwidth);
xmax = ceil(xmax+hwidth);
ymax = ceil(ymax+hwidth);
xsize = xmax-xmin;
ysize = ymax-ymin;
if(xsize<1)
xsize = 1;
if(ysize<1)
ysize = 1;
thebm = bmnew(xsize,ysize);
thebm->xorig = -xmin;
thebm->yorig = -ymin;
mymat = *mat;
mymat.tx -= (xmin+0.5);
mymat.ty -= (ymin+0.5);
scanbeginscan();
execcharprog(cd->data,&mymat,scanfunc);
scanendscan();
return thebm;
}
}
thebm = bmnew(1,1);
return thebm;
}